#include "seniorsendcycle.h"
#include "ui_seniorsendcycle.h"

SeniorSendCycle::SeniorSendCycle(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SeniorSendCycle)
{
    ui->setupUi(this);

    InitTitlepar();

    this->setWindowModality(Qt::ApplicationModal);
    this->setWindowTitle("高级循环发送界面");

    m_nUInum = 0;

    // 初始化表格
    ShowEventsInit();
}

SeniorSendCycle::~SeniorSendCycle()
{
    delete ui;
}

void SeniorSendCycle::InitTitlepar()
{
    QDesktopWidget* desktop = QApplication::desktop();

    m_selMainWidget = new WidgetPar; //创建一个QWidget容器
    m_selMainWidget->setWindowFlags(Qt::FramelessWindowHint);//将这个QWidget的边框去掉

    this->setParent(m_selMainWidget);//重新设置这个UI界面的父对象为QWidget
    TitleBar *pTitleBar = new TitleBar(m_selMainWidget); //定义一个标题栏类

    pTitleBar->showMinmizeBtn(false);
    pTitleBar->showMaxmizeBtn(false);

    this->installEventFilter(pTitleBar);//安装事件过滤器
    QGridLayout *pLayout = new QGridLayout();//创建一个整体布局器
    pLayout->addWidget(pTitleBar);  //添加标题栏
    pLayout->addWidget(this);       //添加UI界面
    pLayout->setSpacing(0);         //布局之间的距离
    pLayout->setContentsMargins(0, 0, 0, 0); //布局器的四周边距
    m_selMainWidget->setLayout(pLayout);  //将这个布局器设置在QWidget上
    m_selMainWidget->setSizePolicy(this->sizePolicy());
    m_selMainWidget->setMaximumSize(this->maximumSize());
    m_selMainWidget->setMinimumWidth(this->minimumWidth() + 2);
    if (this->minimumHeight() + pTitleBar->height() + 10 > 60)
    {
        m_selMainWidget->setMinimumHeight(this->minimumHeight() + pTitleBar->height() + 10);
    }
    else
    {
        m_selMainWidget->setMinimumHeight(pTitleBar->height() + 2);
    }
    m_selMainWidget->setGeometry((desktop->width() - this->width())/2, (desktop->height() - this->height() - pTitleBar->height())/2, this->width(), this->height() + pTitleBar->height() + 10);
    m_selMainWidget->setTitleHeight(static_cast<uint>(pTitleBar->height()));

    connect(m_selMainWidget, &WidgetPar::CloseSignal, this, &SeniorSendCycle::closeEvent);
    m_selMainWidget->setWidgetResizable(false);  // 设置窗体不可缩放
    m_selMainWidget->setWindowModality(Qt::ApplicationModal);

    m_selMainWidget->setWindowTitle(QString("高级循环发送界面"));
    this->setWindowTitle(QString("高级循环发送界面"));
    setWindowIcon(QIcon(":/image/DCDA.ico"));
}

void SeniorSendCycle::InitQSS()
{
    QFile file(g_sInitQSSPath);
    bool isOK = file.open(QFile::ReadOnly);
    if (isOK)
    {
        QTextStream filetext(&file);
        QString stylesheet = filetext.readAll();
        m_selMainWidget->setStyleSheet(stylesheet);
    }
    file.close();
}

void SeniorSendCycle::show()
{
    m_selMainWidget->show();
}

///
/// \brief 关闭窗口
///
void SeniorSendCycle::on_btn_close_clicked()
{
    m_selMainWidget->close();
}

void SeniorSendCycle::closeEvent(QCloseEvent *event)
{
    bool sameok = false, overstate = false;
    emit JudgeDataSignal(sameok, overstate, m_CycleDatas, ui->spinBox_EventsInterval->value(), m_nUInum);
    while(!overstate); // 等待结束
    if (!sameok)  // 如果内容不一致
    {
        QMessageBox message(this);
        message.setWindowTitle("提示");
        message.setText("检测到修改内容尚未保存！点击关闭将会丢失数据！是否继续？");
        message.addButton(tr("确认"), QMessageBox::ActionRole);
        message.addButton(tr("取消"), QMessageBox::ActionRole);
        int isok = message.exec();
        if (isok == 1)
        {
            event->ignore();
            return ;
        }
    }
    event->accept();
}

///
/// \brief 初始化表格
///
void SeniorSendCycle::ShowEventsInit()
{
    m_staCycle = new QStandardItemModel();
    m_staCycle->setColumnCount(2);
    m_staCycle->setHeaderData(0, Qt::Horizontal, QStringLiteral("事件名称"));
    m_staCycle->setHeaderData(1, Qt::Horizontal, QStringLiteral("延时(ms)"));
    ui->tableView_ShowEvents->setModel(m_staCycle);
    ui->tableView_ShowEvents->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);  // 表头信息显示居中
    ui->tableView_ShowEvents->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); // Fixed 为设置列宽不可变
    ui->tableView_ShowEvents->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed); // Stretch 为设置列宽可变
    ui->tableView_ShowEvents->setColumnWidth(0, 160);
    ui->tableView_ShowEvents->setColumnWidth(1, 80);// 设置列的宽度
    ui->tableView_ShowEvents->setSelectionMode(QAbstractItemView::SingleSelection); // 设定只能选择一行，不能选择多行
    ui->tableView_ShowEvents->setSelectionBehavior(QAbstractItemView::SelectRows);  // 设置选中时整行选中
    ui->tableView_ShowEvents->setEditTriggers(QAbstractItemView::NoEditTriggers);  // 设置表格属性只读，不能编辑
}

///
/// \brief 打开界面的时候自动设置数据
/// \param CycleDatas
///
void SeniorSendCycle::SetData(QList<CycleData> CycleDatas, int data)
{
    m_CycleDatas = CycleDatas;
    ShowEventsClear();
    for (int i = 0; i < m_CycleDatas.count(); i++)
    {
        ShowEventsAdd(m_CycleDatas[i]);
    }
    ui->spinBox_EventsInterval->setValue(data);
    ui->lineEdit_EventName->clear();
    ui->textEdit_EventSendData->clear();
    ui->checkBox_EventHex->setChecked(false);
    ui->spinBox_EventDelay->setValue(1000);
}

void SeniorSendCycle::SetUInum(int uinum)
{
    m_nUInum = uinum;
}

///
/// \brief 表格添加内容
/// \param sc
///
void SeniorSendCycle::ShowEventsAdd(CycleData sc)
{
    QStandardItem *standItem1 = new QStandardItem(tr("%1").arg(sc.name));
    QStandardItem *standItem2 = new QStandardItem(tr("%1").arg(sc.delay));
    m_staCycle->insertRow(m_staCycle->rowCount());
    m_staCycle->setItem(m_staCycle->rowCount() - 1, 0, standItem1);
    m_staCycle->setItem(m_staCycle->rowCount() - 1, 1, standItem2);
    m_staCycle->item(m_staCycle->rowCount() - 1, 0)->setTextAlignment(Qt::AlignCenter);
    m_staCycle->item(m_staCycle->rowCount() - 1, 1)->setTextAlignment(Qt::AlignCenter);
}

///
/// \brief 表格插入内容
/// \param row
/// \param sc
///
void SeniorSendCycle::ShowEventsInsert(int row, CycleData sc)
{
    QStandardItem *standItem1 = new QStandardItem(tr("%1").arg(sc.name));
    QStandardItem *standItem2 = new QStandardItem(tr("%1").arg(sc.delay));
    m_staCycle->insertRow(row);
    m_staCycle->setItem(row, 0, standItem1);
    m_staCycle->setItem(row, 1, standItem2);
    m_staCycle->item(row, 0)->setTextAlignment(Qt::AlignCenter);
    m_staCycle->item(row, 1)->setTextAlignment(Qt::AlignCenter);
}

///
/// \brief 表格修改内容
/// \param row
/// \param sc
///
void SeniorSendCycle::ShowEventsRevise(int row, CycleData sc)
{
    m_staCycle->item(row, 0)->setText(sc.name);
    m_staCycle->item(row, 1)->setText(QString("%1").arg(sc.delay));
}

///
/// \brief 表格删除内容
/// \param row
///
void SeniorSendCycle::ShowEventsRemove(int row)
{
    m_staCycle->removeRow(row);
}

///
/// \brief 清空表格显示
///
void SeniorSendCycle::ShowEventsClear()
{
    m_staCycle->removeRows(0, m_staCycle->rowCount());
}

///
/// \brief 增加事件
///
void SeniorSendCycle::on_btn_add_clicked()
{
    CycleData sc;
    sc.name = ui->lineEdit_EventName->text();
    sc.senddata = ui->textEdit_EventSendData->toPlainText();
    sc.isHex = ui->checkBox_EventHex->isChecked();
    sc.delay = static_cast<unsigned int>(ui->spinBox_EventDelay->value());
    if (sc.name.isEmpty())
    {
        inform("添加失败！请输入名称！");
        return ;
    }
    if (sc.isHex)
    {
        if (!toHex(sc.senddata))
        {
            inform("发送数据不是Hex数据！请重新填写！");
            return ;
        }
    }
    m_CycleDatas.append(sc);
    ShowEventsAdd(sc);
}

///
/// \brief 插入事件
///
void SeniorSendCycle::on_btn_insert_clicked()
{
    if (m_CycleChoose > m_CycleDatas.count())
    {
        on_btn_add_clicked();
    }
    else
    {
        CycleData sc;
        sc.name = ui->lineEdit_EventName->text();
        sc.senddata = ui->textEdit_EventSendData->toPlainText();
        sc.isHex = ui->checkBox_EventHex->isChecked();
        sc.delay = static_cast<unsigned int>(ui->spinBox_EventDelay->value());
        if (sc.name.isEmpty())
        {
            inform("添加失败！请输入名称！");
            return ;
        }
        if (sc.isHex)
        {
            if (!toHex(sc.senddata))
            {
                inform("发送数据不是Hex数据！请重新填写！");
                return ;
            }
        }
        m_CycleDatas.insert(m_CycleChoose, sc);
        ShowEventsInsert(m_CycleChoose, sc);
    }
}

///
/// \brief 修改事件
///
void SeniorSendCycle::on_btn_revise_clicked()
{
    if (m_CycleChoose >= 0 && m_CycleChoose < m_CycleDatas.count())
    {
        CycleData sc;
        sc.name = ui->lineEdit_EventName->text();
        sc.senddata = ui->textEdit_EventSendData->toPlainText();
        sc.isHex = ui->checkBox_EventHex->isChecked();
        sc.delay = static_cast<unsigned int>(ui->spinBox_EventDelay->value());
        if (sc.name.isEmpty())
        {
            inform("修改失败！请输入名称！");
            return ;
        }
        if (sc.isHex)
        {
            if (!toHex(sc.senddata))
            {
                inform("发送数据不是Hex数据！请重新填写！");
                return ;
            }
        }
        m_CycleDatas[m_CycleChoose] = sc;
        ShowEventsRevise(m_CycleChoose, sc);
    }
    else
    {
        inform("修改失败！请先选择对象！");
    }
}

///
/// \brief 删除事件
///
void SeniorSendCycle::on_btn_delete_clicked()
{
    if (m_CycleChoose >= 0 && m_CycleChoose < m_CycleDatas.count())
    {
        m_CycleDatas.removeAt(m_CycleChoose);
        ShowEventsRemove(m_CycleChoose);
    }
    else
    {
        inform("删除失败！请先选择对象！");
    }
}

///
/// \brief 单击表格
/// \param index
///
void SeniorSendCycle::on_tableView_ShowEvents_clicked(const QModelIndex &index)
{
    m_CycleChoose = index.row();
    CycleData sc = m_CycleDatas[m_CycleChoose];
    ui->lineEdit_EventName->setText(sc.name);
    ui->textEdit_EventSendData->setText(sc.senddata);
    ui->checkBox_EventHex->setChecked(sc.isHex);
    ui->spinBox_EventDelay->setValue(static_cast<int>(sc.delay));
}

///
/// \brief 弹窗通知
/// \param strdata
///
void SeniorSendCycle::inform(QString strdata)
{
    QMessageBox m_r;

    WidgetPar *wid;
    wid = new WidgetPar;
    wid->setWindowFlags(Qt::FramelessWindowHint);
    wid->setWindowModality(Qt::ApplicationModal);
    m_r.setParent(wid);
    TitleBar *titbar = new TitleBar(wid);

    titbar->showMinmizeBtn(false);
    titbar->showMaxmizeBtn(false);
    titbar->EnableCloseBtn(false);

    m_r.installEventFilter(titbar);
    QGridLayout *layout = new QGridLayout();

    layout->addWidget(titbar);  //添加标题栏
    layout->addWidget(&m_r);       //添加UI界面
    layout->setSpacing(0);         //布局之间的距离
    layout->setContentsMargins(0, 0, 0, 0); //布局器的四周边距
    wid->setLayout(layout);  //将这个布局器设置在QWidget上
    wid->setSizePolicy(m_r.sizePolicy());
    wid->setMaximumSize(m_r.maximumSize());
    wid->setMinimumWidth(m_r.minimumWidth() + 2);

    wid->setWidgetResizable(false);

    wid->move(m_selMainWidget->x() + (m_selMainWidget->width() - 150 - 3*strdata.length())/2, m_selMainWidget->y() + (m_selMainWidget->height() - (titbar->height() + 50))/2);
    wid->setTitleHeight(static_cast<uint>(titbar->height()));

    m_r.setWindowTitle("提示");
    m_r.setWindowIcon(QIcon(":/image/DCDA.ico"));
    m_r.setText(strdata);

    QFile file(g_sInitQSSPath);
    bool isOK = file.open(QFile::ReadOnly);
    if (isOK)
    {
        QTextStream filetext(&file);
        QString stylesheet = filetext.readAll();
        wid->setStyleSheet(stylesheet);
    }
    file.close();

    wid->show();
    wid->setSizePolicy(m_r.sizePolicy());
    wid->setMaximumSize(m_r.maximumSize());
    wid->setMinimumWidth(m_r.minimumWidth() + 2);
    m_r.exec();
    wid->close();
    titbar->deleteLater();
    layout->deleteLater();
    wid->deleteLater();
    titbar = nullptr;
    layout = nullptr;
    wid = nullptr;
}

///
/// \brief 确定
///
void SeniorSendCycle::on_btn_ok_clicked()
{
    emit FinishSignal(m_CycleDatas, static_cast<unsigned int>(ui->spinBox_EventsInterval->value()), m_nUInum);
    m_selMainWidget->close();
}

///
/// \brief 导入高级循环
///
void SeniorSendCycle::on_btn_import_clicked()
{
    QString path = QFileDialog::getOpenFileName(
                this,
                "导入高级循环发送事件",
                "/",
                "XML(*.xml)"
                );
    if (!path.isEmpty())
    {
        bool isOK = ReadXml(path);
        if (!isOK)
        {
            inform("导入失败！");
        }
    }
}

///
/// \brief 导出高级循环
///
void SeniorSendCycle::on_btn_derive_clicked()
{
    if (m_CycleDatas.count() == 0)
    {
        inform("当前无数据，导出内容将为空，请填写好内容后再导出！");
        return ;
    }
    QString path = QFileDialog::getSaveFileName(this, "导出高级循环发送事件", "/", "XML(*.xml)");
    if (!path.isEmpty())
    {
        bool isOK = SaveXml(path);
        if (!isOK)
        {
            inform("导出失败！");
        }
    }
}

///
/// \brief 保存高级循环
/// \param path
///
bool SeniorSendCycle::SaveXml(QString path)
{
    QFile file;
    file.setFileName(path);
    if (!file.open(QFile::WriteOnly|QFile::Truncate))
    {
        file.close();
        return false;
    }
    QDomDocument doc;
    QDomProcessingInstruction xmlInstruction = doc.createProcessingInstruction("xml", "version=\"1.0.1\" encoding=\"UTF-8\"");
    //QDomComment comment = doc.createComment(QString::fromLocal8Bit("高级循环发送"));
    QDomComment comment = doc.createComment(QString("高级循环发送"));
    doc.appendChild(xmlInstruction);   // 开始文档（XML声名）
    doc.appendChild(comment);          // 注释

    QDomElement root = doc.createElement("root");
    doc.appendChild(root);

    QDomElement cycledatas = doc.createElement("cycledatas");
    cycledatas.setAttribute("Delay", ui->spinBox_EventsInterval->value());
    root.appendChild(cycledatas);

    for (int i = 0; i < m_CycleDatas.count(); i++)
    {
        QDomElement cycle = doc.createElement(QString("cycle_%1").arg(i+1));
        cycle.setAttribute("Name", m_CycleDatas[i].name);
        cycle.setAttribute("Delay", m_CycleDatas[i].delay);
        cycle.setAttribute("IsHex", m_CycleDatas[i].isHex);
        cycle.setAttribute("SendData", m_CycleDatas[i].senddata);
        cycledatas.appendChild(cycle);
    }

    QTextStream out_stream(&file);
    doc.save(out_stream, 4);
    file.close();
    return true;
}

///
/// \brief 读取高级循环
/// \param path
///
bool SeniorSendCycle::ReadXml(QString path)
{
    QFile file(path);
    if (!file.open(QFile::ReadOnly))
    {
        file.close();
        return false;
    }
    QDomDocument doc;
    if (!doc.setContent(&file))
    {
        file.close();
        return false;
    }
    file.close();

    m_CycleDatas.clear();
    ShowEventsClear();

    QDomElement root = doc.documentElement();
    QDomNode cycledatas = root.childNodes().at(0);
    if (cycledatas.hasAttributes())
    {
        QDomNamedNodeMap attrs = cycledatas.attributes();
        for (int i = 0; i < attrs.count(); i++)
        {
            QDomNode n = attrs.item(i);
            QString nodeName = n.nodeName();
            QString nodeValue = n.nodeValue();
            if (nodeName == "Delay")
            {
                if (!nodeValue.isEmpty())
                {
                    ui->spinBox_EventsInterval->setValue(nodeValue.toInt());
                }
            }
        }
    }
    if (cycledatas.hasChildNodes())
    {
        QDomNodeList cycles = cycledatas.childNodes();
        for (int i = 0; i < cycles.count(); i++)
        {
            QDomNode cycle = cycles.at(i);
            if (cycle.hasAttributes())
            {
                CycleData spcycledata;
                QDomNamedNodeMap attrs = cycle.attributes();
                for (int i = 0; i < attrs.count(); i++)
                {
                    QDomNode n = attrs.item(i);
                    QString nodeName = n.nodeName();
                    QString nodeValue = n.nodeValue();
                    if (nodeName == "Name")
                    {
                        if (!nodeValue.isEmpty())
                        {
                            spcycledata.name = nodeValue;
                        }
                    }
                    else if (nodeName == "Delay")
                    {
                        if (!nodeValue.isEmpty())
                        {
                            spcycledata.delay = static_cast<unsigned int>(nodeValue.toInt());
                        }
                    }
                    else if (nodeName == "IsHex")
                    {
                        if (!nodeValue.isEmpty())
                        {
                            spcycledata.isHex = static_cast<bool>(nodeValue.toInt());
                        }
                    }
                    else if (nodeName == "SendData")
                    {
                        if (!nodeValue.isEmpty())
                        {
                            spcycledata.senddata = nodeValue;
                        }
                    }
                }
                m_CycleDatas.append(spcycledata);
                ShowEventsAdd(spcycledata);
            }
        }
    }

    return true;
}
